﻿using System.Diagnostics.Contracts;
using System.Reactive.Concurrency;
using System.Threading;

namespace System.Reactive
{
	public static class Observer
	{
		public static IObserver<T> AsObserver<T>(this IObserver<T> observer)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> Create<T>(Action<T> onNext)
		{
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> Create<T>(Action<T> onNext, Action onCompleted)
		{
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Requires(onCompleted != null, null, "onCompleted != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> Create<T>(Action<T> onNext, Action<Exception> onError)
		{
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Requires(onError != null, null, "onError != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> Create<T>(Action<T> onNext, Action<Exception> onError, Action onCompleted)
		{
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Requires(onError != null, null, "onError != null");
			Contract.Requires(onCompleted != null, null, "onCompleted != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> NotifyOn<T>(this IObserver<T> observer, IScheduler scheduler)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> NotifyOn<T>(this IObserver<T> observer, SynchronizationContext context)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Requires(context != null, null, "context != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> Synchronize<T>(IObserver<T> observer)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IObserver<T> Synchronize<T>(IObserver<T> observer, object gate)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Requires(gate != null, null, "gate != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static Action<Notification<T>> ToNotifier<T>(this IObserver<T> observer)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Ensures(Contract.Result<Action<Notification<T>>>() != null, null, "Contract.Result<Action<Notification<T>>>() != null");
			return null;
		}

		public static IObserver<T> ToObserver<T>(this Action<Notification<T>> handler)
		{
			Contract.Requires(handler != null, null, "handler != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

#if !SILVERLIGHT
		public static IObserver<T> ToObserver<T>(this IProgress<T> progress)
		{
			Contract.Requires(progress != null, null, "progress != null");
			Contract.Ensures(Contract.Result<IObserver<T>>() != null, null, "Contract.Result<IObserver<T>>() != null");
			return null;
		}

		public static IProgress<T> ToProgress<T>(this IObserver<T> observer)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Ensures(Contract.Result<IProgress<T>>() != null, null, "Contract.Result<IProgress<T>>() != null");
			return null;
		}

		public static IProgress<T> ToProgress<T>(this IObserver<T> observer, IScheduler scheduler)
		{
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IProgress<T>>() != null, null, "Contract.Result<IProgress<T>>() != null");
			return null;
		}
#endif
	}
}